﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.IO;
using BartonExtension;
using ProtoBuf;
using StackExchange.Redis;
using Cache.Model;

namespace Cache.Utils
{
    public static class CacheUtils
    {
        public static T CacheGet<T>(this IDatabase cache, string key)
        {
            return SerializeManager.Deserialize<T>(cache.StringGet(key));
        }

        public static CacheObject CacheGet(this IDatabase cache, string key)
        {
            return SerializeManager.Deserialize<CacheObject>(cache.StringGet(key));
        }
        public static async Task<CacheObject> CacheGetAsync(this IDatabase cache, string key)
        {
            var obj = await CacheGetAsync<CacheObject>(cache, key);
            return obj;
        }
        public static async Task<T> CacheGetAsync<T>(this IDatabase cache, string key)
        {
            if(cache.KeyExists(key))
            {
                var value = await cache.StringGetAsync(key);
                return SerializeManager.Deserialize<T>(value);
            }
            return default(T);
        
        }
        public static async Task<CachingResult<T>> CacheSetAsync<T>(this IDatabase cache, T cachedObject,string key)
        {
            CachingResult<T> result = new CachingResult<T>();
            bool cacheSuccessFlag = await cache.StringSetAsync(key, cachedObject.Serialize());
            result.isSuccessCached = cacheSuccessFlag;
            result.objectToCache = cachedObject;
            result.timestamp = DateTime.Now.GetTimeIntervalFrom1970WithDateTime();
            return result;
        }
        public static async Task<CachingResult<CacheObject>> CacheSetAsync(this IDatabase cache, CacheObject cachedObject)
        {
            CachingResult<CacheObject> result = new CachingResult<CacheObject>();
            bool cacheSuccessFlag = await cache.StringSetAsync(cachedObject.cacheIdentifier, cachedObject.Serialize());
            result.isSuccessCached = cacheSuccessFlag;
            result.objectToCache = cachedObject;
            result.timestamp = DateTime.Now.GetTimeIntervalFrom1970WithDateTime();
            return result;
        }

        public static CachingResult<CacheObject> CacheSet(this IDatabase cache, CacheObject cachedObject)
        {
            CachingResult<CacheObject> result = new CachingResult<CacheObject>();
            bool cacheSuccessFlag = cache.StringSet(cachedObject.cacheIdentifier, cachedObject.Serialize());
            result.isSuccessCached = cacheSuccessFlag;
            result.objectToCache = cachedObject;
            result.timestamp = DateTime.Now.GetTimeIntervalFrom1970WithDateTime();
            return result;
        }
        public static CachingResult<T> CacheSet<T>(this IDatabase cache,T cachedObject,string key)
        {
            CachingResult<T> result = new CachingResult<T>();
            bool cacheSuccessFlag = cache.StringSet(key, cachedObject.Serialize());
            result.isSuccessCached = cacheSuccessFlag;
            result.objectToCache = cachedObject;
            result.timestamp = DateTime.Now.GetTimeIntervalFrom1970WithDateTime();
            return result;
        }
        public static bool RemoveCache(this IDatabase cache,string key)
        {
            return cache.KeyDelete(key);
        }
        public static Task<bool> RemoveCacheAsync(this IDatabase cache,string key)
        {
            return cache.KeyDeleteAsync(key);
        }
    }
}
